#include "phy_utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/ethtool.h>
#include <linux/sockios.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include <sys/time.h>
#include <ifaddrs.h>
#include <netdb.h>
int phy_interface_exists(const char *interface) {
    return check_interface_exists(interface);
}

int phy_get_interface_info(const char *interface, phy_interface_info_t *info) {
    if (!info || !interface) {
        return -1;
    }
    
    memset(info, 0, sizeof(phy_interface_info_t));
    strncpy(info->name, interface, sizeof(info->name) - 1);
    
    // 获取基本信息
    info->link_status = phy_check_link_status(interface);
    info->speed = phy_get_link_speed(interface);
    info->duplex = phy_get_duplex_mode(interface);
    info->autoneg = phy_get_autoneg_status(interface);
    
    // 获取统计信息
    phy_stats_t stats;
    if (get_phy_stats(interface, &stats) == 0) {
        info->rx_packets = stats.rx_packets;
        info->tx_packets = stats.tx_packets;
        info->rx_bytes = stats.rx_bytes;
        info->tx_bytes = stats.tx_bytes;
        info->rx_errors = stats.rx_errors;
        info->tx_errors = stats.tx_errors;
    }
    
    return 0;
}

void phy_print_interface_info(const phy_interface_info_t *info) {
    if (!info) return;
    
    printf("网络接口信息:\n");
    printf("  接口名称: %s\n", info->name);
    printf("  链路状态: %s\n", info->link_status == PHY_LINK_UP ? "UP" : "DOWN");
    printf("  链路速度: %d Mbps\n", info->speed);
    printf("  双工模式: %s\n", info->duplex ? "全双工" : "半双工");
    printf("  自协商: %s\n", info->autoneg ? "启用" : "禁用");
    printf("  接收包数: %lu\n", info->rx_packets);
    printf("  发送包数: %lu\n", info->tx_packets);
    printf("  接收字节: %lu\n", info->rx_bytes);
    printf("  发送字节: %lu\n", info->tx_bytes);
    printf("  接收错误: %lu\n", info->rx_errors);
    printf("  发送错误: %lu\n", info->tx_errors);
}

void phy_show_all_interfaces(void) {
    struct ifaddrs *ifaddrs_ptr, *ifa;
    
    if (getifaddrs(&ifaddrs_ptr) == -1) {
        perror("getifaddrs");
        return;
    }
    
    printf("可用的网络接口:\n");
    for (ifa = ifaddrs_ptr; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_PACKET) {
            printf("  %s\n", ifa->ifa_name);
        }
    }
    
    freeifaddrs(ifaddrs_ptr);
}

int phy_check_link_status(const char *interface) {
    return get_link_status(interface);
}

int phy_get_link_speed(const char *interface) {
    return get_link_speed(interface);
}

int phy_get_duplex_mode(const char *interface) {
    // 简化实现，返回全双工
    return 1;
}

int phy_get_autoneg_status(const char *interface) {
    // 简化实现，返回启用
    return 1;
}

// 测试运行函数
int phy_run_speed_test(const char *interface, const char *target_host, 
                       const phy_speed_test_config_t *config, 
                       phy_speed_test_result_t *result) {
    // 使用内部的速度测试函数
    return test_speed(interface, (phy_speed_test_config_t*)config, result);
}

void phy_print_speed_test_result(const phy_speed_test_result_t *result) {
    if (!result) return;
    
    printf("速度测试结果:\n");
    printf("  TCP下载速度: %.2f Mbps\n", result->tcp_download_mbps);
    printf("  TCP上传速度: %.2f Mbps\n", result->tcp_upload_mbps);
    printf("  接收包数: %d\n", result->packets_received);
    printf("  发送包数: %d\n", result->packets_sent);
    printf("  丢包率: %.2f%%\n", result->packet_loss_rate);
}

int phy_run_latency_test(const char *interface, const char *target_host, 
                         int packet_count, phy_latency_test_result_t *result) {
    phy_latency_test_config_t config = {
        .count = packet_count,
        .interval_ms = 1000,
        .packet_size = 64,
        .timeout_ms = 5000
    };
    strncpy(config.target_host, target_host, sizeof(config.target_host) - 1);
    
    return test_latency(interface, &config, result);
}

void phy_print_latency_test_result(const phy_latency_test_result_t *result) {
    if (!result) return;
    
    printf("延迟测试结果:\n");
    printf("  平均延迟: %.2f ms\n", result->avg_latency_ms);
    printf("  最小延迟: %.2f ms\n", result->min_latency_ms);
    printf("  最大延迟: %.2f ms\n", result->max_latency_ms);
    printf("  丢包率: %.2f%%\n", result->packet_loss_rate);
}

int phy_run_stability_test(const char *interface, const char *target_host,
                          const phy_stability_test_config_t *config,
                          phy_stability_test_result_t *result) {
    return test_stability(interface, (phy_stability_test_config_t*)config, result);
}

void phy_print_stability_test_result(const phy_stability_test_result_t *result) {
    if (!result) return;
    
    printf("稳定性测试结果:\n");
    printf("  正常运行时间: %.2f%%\n", result->uptime_percentage);
    printf("  链路状态变化: %d\n", result->link_state_changes);
    printf("  总错误包: %lu\n", result->total_errors);
    printf("  总数据包: %lu\n", result->total_packets);
}

int phy_run_stress_test(const char *interface, const char *target_host,
                       const phy_stress_test_config_t *config,
                       phy_stress_test_result_t *result) {
    return test_stress(interface, (phy_stress_test_config_t*)config, result);
}

void phy_print_stress_test_result(const phy_stress_test_result_t *result) {
    if (!result) return;
    
    printf("压力测试结果:\n");
    printf("  平均吞吐量: %.2f Mbps\n", result->avg_throughput_mbps);
    printf("  最大吞吐量: %.2f Mbps\n", result->max_throughput_mbps);
    printf("  总连接数: %lu\n", result->total_connections);
    printf("  失败连接: %lu\n", result->failed_connections);
    printf("  传输字节: %lu\n", result->total_bytes_transferred);
}

// 监控函数
int phy_start_monitor(const char *interface, const phy_monitor_config_t *config) {
    return start_monitor(interface, 0, NULL);
}

int phy_stop_monitor(const char *interface) {
    return stop_monitor();
}

int phy_get_monitor_stats(const char *interface, phy_monitor_stats_t *stats) {
    if (!stats) return -1;
    
    phy_stats_t phy_stats;
    if (get_phy_stats(interface, &phy_stats) != 0) {
        return -1;
    }
    
    stats->timestamp = time(NULL);
    stats->rx_packets = phy_stats.rx_packets;
    stats->tx_packets = phy_stats.tx_packets;
    stats->rx_bytes = phy_stats.rx_bytes;
    stats->tx_bytes = phy_stats.tx_bytes;
    stats->rx_errors = phy_stats.rx_errors;
    stats->tx_errors = phy_stats.tx_errors;
    stats->rx_dropped = phy_stats.rx_dropped;
    stats->tx_dropped = phy_stats.tx_dropped;
    stats->link_status = phy_check_link_status(interface);
    
    return 0;
}

void phy_print_monitor_stats(const phy_monitor_stats_t *stats) {
    if (!stats) return;
    
    printf("监控统计信息:\n");
    printf("  时间戳: %ld\n", stats->timestamp);
    printf("  接收包数: %lu\n", stats->rx_packets);
    printf("  发送包数: %lu\n", stats->tx_packets);
    printf("  接收字节: %lu\n", stats->rx_bytes);
    printf("  发送字节: %lu\n", stats->tx_bytes);
    printf("  接收错误: %lu\n", stats->rx_errors);
    printf("  发送错误: %lu\n", stats->tx_errors);
}

// 工具函数
static int verbose_mode = 0;

void phy_set_verbose_mode(int verbose) {
    verbose_mode = verbose;
}
int check_interface_exists(const char *interface) {
    struct ifaddrs *ifaddrs_ptr, *ifa;
    int found = 0;
    
    if (getifaddrs(&ifaddrs_ptr) == -1) {
        perror("getifaddrs");
        return 0;
    }
    
    for (ifa = ifaddrs_ptr; ifa != NULL; ifa = ifa->ifa_next) {
        if (strcmp(ifa->ifa_name, interface) == 0) {
            found = 1;
            break;
        }
    }
    
    freeifaddrs(ifaddrs_ptr);
    return found;
}

int get_link_status(const char *interface) {
    FILE *fp;
    char path[256];
    char status[32];
    
    snprintf(path, sizeof(path), "/sys/class/net/%s/carrier", interface);
    fp = fopen(path, "r");
    if (!fp) {
        return -1;
    }
    
    if (fgets(status, sizeof(status), fp) != NULL) {
        fclose(fp);
        return (status[0] == '1') ? 1 : 0;
    }
    
    fclose(fp);
    return -1;
}

int get_link_speed(const char *interface) {
    FILE *fp;
    char path[256];
    char speed_str[32];
    int speed;
    
    snprintf(path, sizeof(path), "/sys/class/net/%s/speed", interface);
    fp = fopen(path, "r");
    if (!fp) {
        return -1;
    }
    
    if (fgets(speed_str, sizeof(speed_str), fp) != NULL) {
        speed = atoi(speed_str);
        fclose(fp);
        return speed;
    }
    
    fclose(fp);
    return -1;
}

int get_phy_stats(const char *interface, phy_stats_t *stats) {
    FILE *fp;
    char line[256];
    char *token;
    
    memset(stats, 0, sizeof(phy_stats_t));
    
    fp = fopen("/proc/net/dev", "r");
    if (!fp) {
        perror("fopen /proc/net/dev");
        return -1;
    }
    
    // 跳过前两行标题
    if (fgets(line, sizeof(line), fp) == NULL) {
        fclose(fp);
        return -1;
    }
    if (fgets(line, sizeof(line), fp) == NULL) {
        fclose(fp);
        return -1;
    }
    
    while (fgets(line, sizeof(line), fp)) {
        token = strtok(line, " :");
        if (token && strncmp(token, interface, strlen(interface)) == 0) {
            // RX统计
            stats->rx_bytes = strtoull(strtok(NULL, " "), NULL, 10);
            stats->rx_packets = strtoull(strtok(NULL, " "), NULL, 10);
            stats->rx_errors = strtoull(strtok(NULL, " "), NULL, 10);
            stats->rx_dropped = strtoull(strtok(NULL, " "), NULL, 10);
            strtok(NULL, " "); // rx_fifo_errors
            strtok(NULL, " "); // rx_frame_errors
            strtok(NULL, " "); // rx_compressed
            strtok(NULL, " "); // rx_multicast
            
            // TX统计
            stats->tx_bytes = strtoull(strtok(NULL, " "), NULL, 10);
            stats->tx_packets = strtoull(strtok(NULL, " "), NULL, 10);
            stats->tx_errors = strtoull(strtok(NULL, " "), NULL, 10);
            stats->tx_dropped = strtoull(strtok(NULL, " "), NULL, 10);
            
            fclose(fp);
            return 0;
        }
    }
    
    fclose(fp);
    return -1;
}

// 链路检测功能
int test_link_status(const char *interface, phy_link_test_config_t *config, phy_link_test_result_t *result) {
    if (!check_interface_exists(interface)) {
        printf("错误：网卡接口 %s 不存在\n", interface);
        return -1;
    }
    
    memset(result, 0, sizeof(phy_link_test_result_t));
    strncpy(result->interface, interface, sizeof(result->interface) - 1);
    
    printf("开始链路状态测试 - 接口: %s\n", interface);
    printf("测试间隔: %d秒, 测试次数: %d\n", config->interval, config->count);
    
    for (int i = 0; i < config->count; i++) {
        int status = get_link_status(interface);
        int speed = get_link_speed(interface);
        
        if (status == 1) {
            result->link_up_count++;
            printf("[%d/%d] 链路状态: UP, 速度: %d Mbps\n", i+1, config->count, speed);
        } else {
            result->link_down_count++;
            printf("[%d/%d] 链路状态: DOWN\n", i+1, config->count);
        }
        
        if (i < config->count - 1) {
            sleep(config->interval);
        }
    }
    
    result->success_rate = (double)result->link_up_count / config->count * 100.0;
    
    printf("\n链路测试完成:\n");
    printf("  链路UP次数: %d\n", result->link_up_count);
    printf("  链路DOWN次数: %d\n", result->link_down_count);
    printf("  链路稳定率: %.2f%%\n", result->success_rate);
    
    return 0;
}

// 速度测试功能
int test_speed(const char *interface, phy_speed_test_config_t *config, phy_speed_test_result_t *result) {
    if (!check_interface_exists(interface)) {
        printf("错误：网卡接口 %s 不存在\n", interface);
        return -1;
    }
    
    memset(result, 0, sizeof(phy_speed_test_result_t));
    
    printf("开始速度测试 - 接口: %s\n", interface);
    printf("测试时长: %d秒\n", config->test_duration);
    
    phy_stats_t stats_before, stats_after;
    
    if (get_phy_stats(interface, &stats_before) != 0) {
        printf("错误：无法获取网卡统计信息\n");
        return -1;
    }
    
    sleep(config->test_duration);
    
    if (get_phy_stats(interface, &stats_after) != 0) {
        printf("错误：无法获取网卡统计信息\n");
        return -1;
    }
    
    // 计算速度
    uint64_t rx_diff = stats_after.rx_bytes - stats_before.rx_bytes;
    uint64_t tx_diff = stats_after.tx_bytes - stats_before.tx_bytes;
    
    result->tcp_download_mbps = (double)(rx_diff * 8) / (config->test_duration * 1024 * 1024);
    result->tcp_upload_mbps = (double)(tx_diff * 8) / (config->test_duration * 1024 * 1024);
    result->packets_received = (stats_after.rx_packets - stats_before.rx_packets);
    result->packets_sent = (stats_after.tx_packets - stats_before.tx_packets);
    
    printf("\n速度测试结果:\n");
    printf("  接收速度: %.2f Mbps (%d 包)\n", result->tcp_download_mbps, result->packets_received);
    printf("  发送速度: %.2f Mbps (%d 包)\n", result->tcp_upload_mbps, result->packets_sent);
    
    return 0;
}

// 延迟测试功能
int test_latency(const char *interface, phy_latency_test_config_t *config, phy_latency_test_result_t *result) {
    if (!check_interface_exists(interface)) {
        printf("错误：网卡接口 %s 不存在\n", interface);
        return -1;
    }
    
    memset(result, 0, sizeof(phy_latency_test_result_t));
    
    printf("开始延迟测试 - 接口: %s\n", interface);
    
    char cmd[512];
    snprintf(cmd, sizeof(cmd), "ping -c %d -i %.3f %s", 
             config->count, config->interval_ms / 1000.0, config->target_host);
    
    FILE *pipe = popen(cmd, "r");
    if (!pipe) {
        perror("popen");
        return -1;
    }
    
    char line[256];
    double total_time = 0.0;
    int success_count = 0;
    double min_time = 999999.0, max_time = 0.0;
    
    while (fgets(line, sizeof(line), pipe)) {
        if (strstr(line, "time=")) {
            char *time_str = strstr(line, "time=") + 5;
            double time_ms = atof(time_str);
            
            total_time += time_ms;
            success_count++;
            
            if (time_ms < min_time) min_time = time_ms;
            if (time_ms > max_time) max_time = time_ms;
            
            printf("ping #%d: %.2f ms\n", success_count, time_ms);
        }
    }
    
    pclose(pipe);
    
    if (success_count > 0) {
        result->avg_latency_ms = total_time / success_count;
        result->min_latency_ms = min_time;
        result->max_latency_ms = max_time;
        result->packet_loss_rate = (double)(config->count - success_count) / config->count * 100.0;
        
        printf("\n延迟测试结果:\n");
        printf("  平均延迟: %.2f ms\n", result->avg_latency_ms);
        printf("  最小延迟: %.2f ms\n", result->min_latency_ms);
        printf("  最大延迟: %.2f ms\n", result->max_latency_ms);
        printf("  丢包率: %.2f%%\n", result->packet_loss_rate);
    } else {
        printf("延迟测试失败：无法ping通目标主机\n");
        return -1;
    }
    
    return 0;
}

// 稳定性测试功能
int test_stability(const char *interface, phy_stability_test_config_t *config, phy_stability_test_result_t *result) {
    if (!check_interface_exists(interface)) {
        printf("错误：网卡接口 %s 不存在\n", interface);
        return -1;
    }
    
    memset(result, 0, sizeof(phy_stability_test_result_t));
    
    printf("开始稳定性测试 - 接口: %s\n", interface);
    printf("测试时长: %d秒, 检查间隔: %d秒\n", config->test_duration, config->ping_interval);
    
    time_t start_time = time(NULL);
    time_t end_time = start_time + config->test_duration;
    int check_count = 0;
    int link_state_changes = 0;
    int prev_link_status = -1;
    
    while (time(NULL) < end_time) {
        int link_status = get_link_status(interface);
        int link_speed = get_link_speed(interface);
        phy_stats_t stats;
        
        check_count++;
        
        // 检测链路状态变化
        if (prev_link_status != -1 && prev_link_status != link_status) {
            link_state_changes++;
        }
        prev_link_status = link_status;
        
        if (link_status == 1) {
            printf("检查 #%d: 链路稳定 (速度: %d Mbps)\n", check_count, link_speed);
        } else {
            printf("检查 #%d: 链路不稳定\n", check_count);
        }
        
        if (get_phy_stats(interface, &stats) == 0) {
            result->total_errors += stats.rx_errors + stats.tx_errors;
            result->total_packets += stats.rx_packets + stats.tx_packets;
        }
        
        sleep(config->ping_interval);
    }
    
    result->link_state_changes = link_state_changes;
    result->uptime_percentage = (double)(check_count - link_state_changes) / check_count * 100.0;
    
    printf("\n稳定性测试结果:\n");
    printf("  总检查次数: %d\n", check_count);
    printf("  链路状态变化: %d\n", result->link_state_changes);
    printf("  稳定性: %.2f%%\n", result->uptime_percentage);
    printf("  总错误包: %lu\n", result->total_errors);
    printf("  总数据包: %lu\n", result->total_packets);
    
    return 0;
}

// 压力测试功能
static volatile int stress_running = 0;

void stress_signal_handler(int sig) {
    stress_running = 0;
    printf("\n收到信号 %d，停止压力测试\n", sig);
}

int test_stress(const char *interface, phy_stress_test_config_t *config, phy_stress_test_result_t *result) {
    if (!check_interface_exists(interface)) {
        printf("错误：网卡接口 %s 不存在\n", interface);
        return -1;
    }
    
    memset(result, 0, sizeof(phy_stress_test_result_t));
    
    printf("开始压力测试 - 接口: %s\n", interface);
    printf("测试时长: %d秒, 并发连接: %d\n", config->test_duration, config->concurrent_connections);
    
    // 注册信号处理器
    signal(SIGINT, stress_signal_handler);
    signal(SIGTERM, stress_signal_handler);
    
    stress_running = 1;
    time_t start_time = time(NULL);
    time_t end_time = start_time + config->test_duration;
    
    phy_stats_t stats_start, stats_current;
    if (get_phy_stats(interface, &stats_start) != 0) {
        printf("错误：无法获取网卡统计信息\n");
        return -1;
    }
    
    int check_count = 0;
    while (stress_running && time(NULL) < end_time) {
        check_count++;
        
        if (get_phy_stats(interface, &stats_current) == 0) {
            result->total_bytes_transferred += (stats_current.rx_bytes - stats_start.rx_bytes) + 
                                             (stats_current.tx_bytes - stats_start.tx_bytes);
        }
        
        // 检查链路状态
        int link_status = get_link_status(interface);
        if (link_status != 1) {
            result->failed_connections++;
            printf("警告：检测到链路故障 (检查 #%d)\n", check_count);
        }
        
        printf("\r压力测试进行中... [%d/%d秒] 失败连接: %lu", 
               (int)(time(NULL) - start_time), config->test_duration, result->failed_connections);
        fflush(stdout);
        
        sleep(1);
    }
    
    result->total_connections = check_count;
    double avg_throughput = (double)result->total_bytes_transferred / (time(NULL) - start_time) / (1024 * 1024);
    result->avg_throughput_mbps = avg_throughput;
    
    printf("\n\n压力测试结果:\n");
    printf("  测试时长: %d秒\n", (int)(time(NULL) - start_time));
    printf("  总连接数: %lu\n", result->total_connections);
    printf("  失败连接: %lu\n", result->failed_connections);
    printf("  总数据量: %lu bytes\n", result->total_bytes_transferred);
    printf("  平均吞吐量: %.2f MB/s\n", result->avg_throughput_mbps);
    
    return 0;
}

// 监控功能实现
static volatile int monitor_running = 0;
static pthread_t monitor_thread;
static FILE *monitor_log = NULL;

typedef struct {
    char interface[32];
    int duration;
    char log_file[256];
} monitor_context_t;

void *monitor_worker(void *arg) {
    monitor_context_t *ctx = (monitor_context_t *)arg;
    time_t start_time = time(NULL);
    
    while (monitor_running && (ctx->duration == 0 || (time(NULL) - start_time) < ctx->duration)) {
        phy_stats_t stats;
        if (get_phy_stats(ctx->interface, &stats) == 0) {
            time_t now = time(NULL);
            char timestamp[64];
            strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", localtime(&now));
            
            if (monitor_log) {
                fprintf(monitor_log, "[%s] Interface: %s, RX: %lu bytes, TX: %lu bytes, Errors: %lu\n",
                       timestamp, ctx->interface, stats.rx_bytes, stats.tx_bytes, 
                       stats.rx_errors + stats.tx_errors);
                fflush(monitor_log);
            }
            
            printf("\r[%s] RX: %lu B, TX: %lu B, Errors: %lu", 
                   timestamp, stats.rx_bytes, stats.tx_bytes, 
                   stats.rx_errors + stats.tx_errors);
            fflush(stdout);
        }
        sleep(1);
    }
    
    monitor_running = 0;
    printf("\n监控已停止\n");
    return NULL;
}

int start_monitor(const char *interface, int duration, const char *log_file) {
    if (monitor_running) {
        printf("监控已在运行中\n");
        return -1;
    }
    
    monitor_context_t *ctx = malloc(sizeof(monitor_context_t));
    if (!ctx) {
        perror("malloc");
        return -1;
    }
    
    strncpy(ctx->interface, interface, sizeof(ctx->interface) - 1);
    ctx->duration = duration;
    
    if (log_file && strlen(log_file) > 0) {
        strncpy(ctx->log_file, log_file, sizeof(ctx->log_file) - 1);
        monitor_log = fopen(log_file, "a");
        if (!monitor_log) {
            perror("fopen log file");
            free(ctx);
            return -1;
        }
    }
    
    monitor_running = 1;
    if (pthread_create(&monitor_thread, NULL, monitor_worker, ctx) != 0) {
        perror("pthread_create");
        monitor_running = 0;
        if (monitor_log) {
            fclose(monitor_log);
            monitor_log = NULL;
        }
        free(ctx);
        return -1;
    }
    
    printf("开始监控网卡 %s，持续时间: %s\n", 
           interface, duration == 0 ? "无限制" : "指定时间");
    return 0;
}

int stop_monitor(void) {
    if (!monitor_running) {
        printf("监控未运行\n");
        return -1;
    }
    
    monitor_running = 0;
    pthread_join(monitor_thread, NULL);
    
    if (monitor_log) {
        fclose(monitor_log);
        monitor_log = NULL;
    }
    
    return 0;
}

void print_monitor_stats(void) {
    if (monitor_running) {
        printf("监控正在运行中...\n");
    } else {
        printf("监控未运行\n");
    }
}